use std::{rc::Rc, cell::RefCell};

use crate::{instructions::base::Instruction, rtda::Frame};


// fcmpg和fcmpl指令用于比较float变量
// 由于浮点数计算有可能产生NaN（Not a Number）值，所以比较两个浮点数时，
// 除了大于、等于、小于之外，还有第4种结果：无法比较。
// fcmpg和fcmpl指令的区别就在于对第4种结果的定义。
// 两个float变量中至少有一个是NaN时，用fcmpg指令比较的结果是1，而用fcmpl指令比较的结果是-1。

// Compare float
#[derive(Debug, Default)]
pub struct FCMPG {}

impl Instruction for FCMPG {
    fn execute(&mut self, frame: Rc<RefCell<Frame>>) {
        _fcmp(frame, true);
    }
}

#[derive(Debug, Default)]
pub struct FCMPL {}

impl Instruction for FCMPL {
    fn execute(&mut self, frame: Rc<RefCell<Frame>>) {
        _fcmp(frame, false);
    }
}

fn _fcmp(frame: Rc<RefCell<Frame>>, g_flag: bool) {
    let stack = frame.borrow().get_operand_stack();
    let v2 = stack.borrow_mut().pop_float();
    let v1=  stack.borrow_mut().pop_float();
    let r = if v1 > v2 { 1 } 
            else if v1 == v2 { 0 } 
            else if v1 < v2 { -1 } 
            else if g_flag { 1 } 
            else {0};
    stack.borrow_mut().push_int(r);
    
}